package com.realw.argus.web.common.velocity;

import java.io.IOException;
import java.io.StringWriter;
import java.util.Map;

import javax.annotation.PostConstruct;

import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.context.Context;
import org.apache.velocity.exception.MethodInvocationException;
import org.apache.velocity.exception.ParseErrorException;
import org.apache.velocity.exception.ResourceNotFoundException;
import org.apache.velocity.exception.VelocityException;
import org.apache.velocity.tools.ToolContext;
import org.apache.velocity.tools.ToolManager;
import org.springframework.core.io.Resource;
import org.springframework.ui.velocity.VelocityEngineFactory;

/**
 * Velocity模板渲染器
 * <p>
 * 支持引擎配置、工具箱配置
 * <p>
 * Note:需要配置为springBean，否则需要显示调用init初始化
 * 
 * @author NeoArgus
 * @see #setConfigLocation
 * @see #setToolboxConfigLocation
 */
public class VelocityRenderer {

	Resource configLocation;

	String toolboxConfigLocation;

	boolean initFlag = false;

	VelocityEngineFactory velocityEngineFactory = new VelocityEngineFactory();

	VelocityEngine velocityEngine;

	ToolManager toolManager = new ToolManager();

	ToolContext toolContext;

	@PostConstruct
	public void init() throws VelocityException, IOException {
		if (initFlag) {
			return;
		}
		// 创建引擎
		velocityEngineFactory.setConfigLocation(configLocation);

		// velocityEngine.addProperty(VelocityEngine.VM_LIBRARY,
		// "org/springframework/web/servlet/view/velocity/spring.vm");

		velocityEngine = velocityEngineFactory.createVelocityEngine();
		// 创建工具箱
		toolManager.configure(toolboxConfigLocation);
		toolContext = toolManager.createContext();
		initFlag = true;
	}

	public String evaluate(Map<String, Object> model, String logTag,
			String instring) throws ParseErrorException,
			MethodInvocationException, ResourceNotFoundException {
		StringWriter out = new StringWriter();
		velocityEngine.evaluate(buildContext(model), out, logTag, instring);
		return out.getBuffer().toString();
	}

	protected Context buildContext(Map<String, Object> model) {
		if (toolContext != null) {
			return new VelocityContext(model, toolContext);
		} else {
			return new VelocityContext(model);
		}
	}

	public Resource getConfigLocation() {
		return configLocation;
	}

	/**
	 * 引擎配置
	 * 
	 * @param configLocation
	 */
	public void setConfigLocation(Resource configLocation) {
		this.configLocation = configLocation;
	}

	public String getToolboxConfigLocation() {
		return toolboxConfigLocation;
	}

	/**
	 * 工具箱配置
	 * 
	 * @param toolboxConfigLocation
	 */
	public void setToolboxConfigLocation(String toolboxConfigLocation) {
		this.toolboxConfigLocation = toolboxConfigLocation;
	}

}
